﻿

from google.appengine.ext import webapp
from google.appengine.ext.webapp.util import run_wsgi_app
from google.appengine.ext import db
from google.appengine.api import mail
from google.appengine.api import urlfetch
import json
import time

#group status: 1 for discussion, 2 for consent. but if user didn't join yet we return 0, anyway.
class Group(db.Model):
  name = db.StringProperty()
  movieName = db.StringProperty()
  movieId = db.StringProperty()
  status = db.StringProperty()
  chat = db.StringListProperty()

class GroupMember(db.Model):
  groupKey = db.StringProperty()
  userId = db.StringProperty()
  userName = db.StringProperty()
  city = db.StringProperty()
  theatre = db.StringProperty()
  day = db.StringProperty()
  hour = db.StringProperty()
  newMember = db.StringProperty()
  newUpdate = db.StringProperty()

class UserPrefs(db.Model):
  userId = db.StringProperty()
  email = db.StringProperty()
  addedToGroupNotify = db.StringProperty()
  otherMemberEnteredOrLeftNotify = db.StringProperty()
  consentNotify = db.StringProperty()

class NewMoviesContent(db.Model):
  content = db.TextProperty()
  weekOfUpdate = db.IntegerProperty()

class AllMoviesContent(db.Model):
  content = db.TextProperty()
  weekOfUpdate = db.IntegerProperty()
  parsedMovieIds = db.StringListProperty()
  
class SingleMovieContent(db.Model):
  content = db.TextProperty()
  movieId = db.StringProperty()
  weekOfUpdate = db.IntegerProperty()

class UpdateLogLine(db.Model):
  time = db.StringProperty()
  lineNum = db.IntegerProperty()
  content = db.StringProperty()

class CurrentParsedMovie(db.Model):
  listIndex = db.IntegerProperty()

    
class MainAppHandler(webapp.RequestHandler):
  debugVersion = False
  newMoviesUrl = "http://www.dapper.net/transform.php?dappName=catchamovieNewMoiesVersion2&transformer=JSON&applyToUrl=http%3A%2F%2Fwww.seret.co.il%2Fmovies%2Findex.asp%3FcatCase%3D1"
  allMoviesUrl = "http://www.dapper.net/transform.php?dappName=catchamovieAllMovies&transformer=JSON&applyToUrl=http%3A%2F%2Fwww.seret.co.il%2Fmovies%2Findex.asp%3FcatCase%3D2"
  singleMovieUrl = "http://www.dapper.net/transform.php?dappName=CAMSingleMovieDapper2&transformer=JSON&v_movieId="
  
  def get(self):
    action = self.request.get('action')
    if(action == 'GetGroupsByUserId'):
        self.HandleGetGroupsByUserId()
    elif(action == 'GetGroupMembers'):
        self.HandleGetGroupMemebers()
    elif(action == 'ChangeGroupMember'):
        self.HandleChangeGroupMember()
    elif(action == 'CreateGroup'):
        self.HandleCreateGroup()
    elif(action == 'UpdateUserPrefs'):
        self.HandleUpdateUserPrefs()
    elif(action == 'GetUserPrefs'):
        self.HandleGetUserPrefs()
    elif(action == 'LeaveGroup'):
        self.HandleLeaveGroup()
    elif(action == 'AddChatLineToGroup'):
        self.HandleAddChatLineToGroup()
    elif(action == 'GetGroupChat'):
        self.HandleGetGroupChat()
    elif(action == 'GetNewMoviesDapp'):
        self.HandleGetNewMoviesDapp()
    elif(action == 'GetAllMoviesDapp'):
        self.HandleGetAllMoviesDapp()
    elif(action == 'GetSingleMovieDapp'):
        self.HandleGetSingleMovieDapp()    
    elif(action == 'ClearGroupChat'):
        self.HandleClearGroupChat()
    elif(action == 'ParseAllMovieIds'):
        self.HandleParseAllMovieIds()
    elif(action == 'GetMoviePreview'):
        self.HandleGetMoviePreview()
    else:
      self.DebugPrint('Could Not Parse Action: %s' % action)

  def DebugPrint(self, text):
    if (self.debugVersion):
      self.response.out.write('$ '+ text+ ' $')

# update group status, if there is a status change
  def UpdateGroupStatus(self, groupObj, groupKeyStr):
    #get members of group
    groupMemberResults = GroupMember.gql('WHERE groupKey=:gk', gk=groupKeyStr)
    #init first member of group
    firstMember = groupMemberResults.get()
    #check consent, first iteration is redundant...
    consent = True
    for member in groupMemberResults:
      if ((member.city != firstMember.city) or (member.city == '0')):
        consent = False
        break
      if ((member.theatre != firstMember.theatre) or (member.theatre == '0')):
        consent = False
        break
      if ((member.day != firstMember.day) or (member.day == '0')):
        consent = False
        break
      if ((member.hour != firstMember.hour) or (member.hour == '0')):
        consent = False
        break
    #update group status, consent (2) or in discussion (1). Undecided is determined separately for each user!
    if (consent == True):
      if (groupObj.status != '2'):
        #update group status
        groupObj.status = '2'
        #send notification mail to (all) group members about consent
        for member in groupMemberResults:
          UserPrefsResults = UserPrefs.gql('WHERE userId = :1', member.userId)
          if (UserPrefsResults.count() != 1):
            self.DebugPrint('Did not exaclty one userPrefs for this user, default is no notification')
          else:
            userPrefs = UserPrefsResults.get()
            if (userPrefs.consentNotify != '1'):
              self.DebugPrint('User did not request to be notified on this event')
            else:
              message = mail.EmailMessage(sender = "CatchAMovie.Admin@gmail.com",
                                          to = userPrefs.email)
              message.subject = unicode("הסכמה כללית בקבוצה", "utf-8") + ": " + groupObj.name
              endl = """
"""
              line1 = unicode(":CatchAMovie התראת", "utf-8")
              line2 = unicode("הסכמה כללית בקבוצה", "utf-8") + ": " + groupObj.name
              line3 = unicode("הנך מוזמן\נת לגלוש אל עמוד האייגוגל שלך ולודא את פרטי היציאה", "utf-8")
              line4 = unicode("!מאחל לך ולחבריך צפיה נעימה CatchAMovie צוות ", "utf-8")
              line5 = "http://www.igoogle.com/ " + unicode(":לינק לאתר אייגוגל","utf-8") 
              message.body = line1 + endl + endl + line2 + endl + line3 + endl + line4 + endl + endl + line5 + endl
              message.send()
    else:
      groupObj.status = '1'
    groupObj.put()
      
  def HandleGetGroupsByUserId(self):
    #Get UserId:
    userId = self.request.get('userId')
    #find groups members that have the recieved userId
    searchResults1 = GroupMember.gql('WHERE userId=:uId', uId=userId)
    groupsResults = []
    j = 1
    for member in searchResults1:
      groupKeyStr = member.groupKey
      newUpdate = member.newUpdate
      groupKey = db.Key(groupKeyStr)
      searchResults2 = Group.gql('WHERE __key__ = :1', groupKey)
      count = searchResults2.count()
      if (count != 1):
        self.DebugPrint('Error, did not find exactly 1 group for this group member')
      else:
        #check if current user did not enter group yet:
        status = searchResults2[0].status
        if (member.newMember == '1'):
          status = '0'        
        groupItem = { 'groupKey' : groupKeyStr,
                      'name' : searchResults2[0].name,
                      'movieName' : searchResults2[0].movieName,
                      'movieId' : searchResults2[0].movieId,
                      'status' : status,
                      'newUpdate' : newUpdate }
        groupsResults.append(groupItem)
      j = j + 1
    self.response.out.write(json.write(groupsResults))
          
  def HandleGetGroupMemebers(self):
    groupKeyStr = self.request.get('groupKey')
    callerUserId = self.request.get('userId')
    GroupMemberSearchResults = GroupMember.gql('WHERE groupKey = :1', groupKeyStr)
    callerSearchResults = GroupMember.gql('WHERE groupKey = :1 AND userId = :2', groupKeyStr, callerUserId)
    if (callerSearchResults.count() != 1):
      self.DebugPrint('Did not find exaclty one user with the given userId in the given group')
    else:
      callerGroupMember = callerSearchResults.get()
      #lower newUpdate flag for caller, on this group:
      callerGroupMember.newUpdate = '0'
      callerGroupMember.put()
      Output = []
      j = 1
      for member in GroupMemberSearchResults:
        #set field consent of members with respect to caller
        friendConsent = '1'
        if ((callerGroupMember.city == member.city) and (callerGroupMember.city != '0')):
          cityConsent = '1'
        else:
          cityConsent = '0'
          friendConsent = '0'
        if ((callerGroupMember.theatre == member.theatre) and (callerGroupMember.theatre != '0')):
          theatreConsent = '1'
        else:
          theatreConsent = '0'
          friendConsent = '0'
        if ((callerGroupMember.day == member.day) and (callerGroupMember.day != '0')):
          dayConsent = '1'
        else:
          dayConsent = '0'
          friendConsent = '0'
        if ((callerGroupMember.hour == member.hour) and (callerGroupMember.hour != '0')):
          hourConsent = '1'
        else:
          hourConsent = '0'
          friendConsent = '0'
        if (member.newMember == '0'):  
          memberOutputItem = { 'groupKey' : member.groupKey, 
                       'userId' : member.userId,
                       'userName' : member.userName,
                       'city' : member.city,
                       'theatre' : member.theatre,
                       'day' : member.day,
                       'hour' : member.hour,
                       'cityConsent' : cityConsent,
                       'theatreConsent' : theatreConsent,
                       'dayConsent' : dayConsent,
                       'hourConsent' : hourConsent,
                       'friendConsent' : friendConsent }
        else:
          memberOutputItem = { 'groupKey' : member.groupKey, 
                       'userId' : member.userId,
                       'userName' : member.userName,
                       'city' : '999',
                       'theatre' : '999',
                       'day' : '999',
                       'hour' : '999',
                       'cityConsent' : cityConsent,
                       'theatreConsent' : theatreConsent,
                       'dayConsent' : dayConsent,
                       'hourConsent' : hourConsent,
                       'friendConsent' : friendConsent }
        Output.append(memberOutputItem)
        j = j + 1
      self.response.out.write(json.write(Output))

  def HandleCreateGroup(self):
    #create a new group  
    group = Group()
    group.name = self.request.get('name')
    group.movieName = self.request.get('movieName')
    group.movieId = self.request.get('movieId')
    group.status =  '1'
    group.chat = []
    numberOfFriends = self.request.get('numberOfFriends')
    group.put()
  #parse recieved userIds and create a GroupMember line for each userId recieved
    for i in range(int(numberOfFriends)):
      userId = self.request.get('userId' + str(i))
      member = GroupMember()
      member.groupKey = str(group.key())
      member.userId = userId
      member.userName = self.request.get('userName' + str(i))
      member.city = '0'
      member.theatre = '0'
      member.day = '0'
      member.hour = '0'
      if (i == 0):
        #creator is not new anyway
        member.newMember = '0'
        member.city = '0'
        member.theatre = '0'
        member.day = '0'
        member.hour = '0'
        #and for his point of view there is no new update to check
        member.newUpdate = '0'
        #remember creator name for Email notification
        creatorName = member.userName
      else:
        member.newMember = '1'
        member.newUpdate = '1'
        #send notification to added user
        searchResults = UserPrefs.gql('WHERE userId = :1', userId)
        if (searchResults.count() == 1):
          userPrefs = searchResults.get()
          if (userPrefs.addedToGroupNotify == '1'):
            message = mail.EmailMessage(sender = "CatchAMovie.Admin@gmail.com",
                                        to = userPrefs.email)
            message.subject = unicode("הנך מוזמן לסרט", "utf-8") + ": " + group.movieName
            endl = """
"""
            line1 = unicode(":CatchAMovie התראת", "utf-8")
            line2 = unicode("מזמין אותך להצטרף אליו לצפיה בסרט", "utf-8") + ": " + group.movieName + " " + creatorName 
            line3 = unicode("שם קבוצת החברים", "utf-8") + ": " + group.name
            line4 = unicode("!הנך מוזמן\נת לגלוש אל עמוד האייגוגל שלך ולהציע היכן ומתי תרצה\י לצפות בסרט", "utf-8")
            line5 = "http://www.igoogle.com/ " + unicode(":לינק לאתר אייגוגל","utf-8") 
            message.body = line1 + endl + endl + line2 + endl + line3 + endl + line4 + endl + endl + line5 + endl
            message.send()
          else:
            self.DebugPrint('User did not request to be notified on this event')
        else:
          self.DebugPrint('Did not exaclty one userPrefs for this user, default is no notification')
      member.put()

##  def HandleDeleteGroup(self):
##    self.DebugPrint('Entered HandleDeleteGroup')
##    groupKeyStr = self.request.get('groupKey')
##    self.DebugPrint('groupKey recieved: %s ' % groupKeyStr)
##    #delete group members
##    searchResults = GroupMember.gql('WHERE groupKey = :1', groupKeyStr)
##    self.DebugPrint('Deleting %s GroupMembers' % searchResults.count())
##    for member in searchResults:
##      member.delete()
##    #now delete the group object
##    groupKey = db.Key(groupKeyStr)
##    searchResults2 = Group.gql('WHERE __key__ = :1', groupKey)
##    self.DebugPrint('Deleting %s Groups' % searchResults2.count())
##    for group in searchResults2:
##      group.delete()

  def HandleChangeGroupMember(self):
    groupKeyStr = self.request.get('groupKey')
    userId = self.request.get('userId')
    #get the group member object
    searchResults = GroupMember.gql('WHERE groupKey = :1 AND userId = :2', groupKeyStr,userId)
    count = searchResults.count()
    if (count != 1):
      self.DebugPrint('Error, did not find exactly 1 group member')
    else:
      #send notifications to other users. first, need the group name for the Email
      groupKey = db.Key(groupKeyStr)
      groupResults = Group.gql('WHERE __key__ = :1', groupKey)
      groupName = groupResults.get().name
      member = searchResults.get()
      #first update parameters
      newUpdate = '0'
      #new city?
      city = self.request.get('city')
      if (city == '') or (city == member.city):
        self.DebugPrint('new city is the same or did not revieve any city, keeping previous city')
      else:
        member.city = city
        newUpdate = '1'
      #new theatre
      theatre = self.request.get('theatre')
      if (theatre == '') or (theatre == member.theatre):
        self.DebugPrint('new theatre is the same or did not revieve any theatre, keeping previous theatre')
      else:
        member.theatre = theatre
        newUpdate = '1'
      #new day
      day = self.request.get('day')
      if (day == '') or (day == member.day):
        self.DebugPrint('new day is the same or did not revieve any day, keeping previous day')
      else:
        member.day = day
        newUpdate = '1'
      #new hour
      hour = self.request.get('hour')
      if (hour == '') or (hour == member.hour):
        self.DebugPrint('new hour is the same or did not revieve any hour, keeping previous hour')
      else:
        member.hour = hour
        newUpdate = '1'
      #udpate anyway that member is no longer a new member to the group:
      member.newMember = '0'
      #put back in DB  
      member.put()
      #update group status
      groupKey = db.Key(groupKeyStr)
      searchResults2 = Group.gql('WHERE __key__ = :1', groupKey)
      groupObj = searchResults2.get()
      self.UpdateGroupStatus(groupObj, groupKeyStr)
      #update and notify other group members of the change in member: can't gql with = and != together...
      otherGroupMembersResults = GroupMember.gql('WHERE groupKey = :1', groupKeyStr)
      for otherMember in otherGroupMembersResults:
        if (otherMember.userId != userId):
          #remember if current group for this member should be shown as newly updated
          otherMember.newUpdate = newUpdate
          otherMember.put()
          #send notification for a new user, if needed
          if (member.newMember == '1'):
            #remember that caller member is no longer new in this group
            member.newMember = '0'
            userPrefsResults = UserPrefs.gql('WHERE userId = :1',otherMember.userId)
            if (userPrefsResults.count() != 1):
              self.DebugPrint('Did not find exactly one userPrefs for this user')
            else:
              userPrefs = userPrefsResults.get()
              if (userPrefs.otherMemberEnteredOrLeftNotify == '1'):
                message = mail.EmailMessage(sender = "CatchAMovie.Admin@gmail.com",
                                            to = userPrefs.email)
                message.subject = unicode("אישר את הצטרפותו לקבוצה", "utf-8") + ": " + groupName + " " + member.userName
                endl = """
"""
                line0 = unicode(":CatchAMovie התראת", "utf-8")
                line1 = unicode("אישר את הצטרפותו לקבוצה", "utf-8") + ": " + groupName + " " + member.userName
                line2 = unicode("!הנך מוזמן\נת לגלוש אל עמוד האייגוגל שלך ולהחליט היכן ומתי תרצה\י לצפות בסרט", "utf-8")
                line3 = "http://www.igoogle.com/ " + unicode(":לינק לאתר אייגוגל","utf-8") 
                message.body = line0 + endl + endl + line1 + endl + line2 + endl + endl + line3
                message.send()

  def HandleUpdateUserPrefs(self):
    userId = self.request.get('userId')
    searchResults = UserPrefs.gql('WHERE userId = :1', userId)
    if (searchResults.count() > 1):
      self.response.out.write('Error in DB, more then one userPrefs for this userId!')
    else:  
      if (searchResults.count() == 0):
        userPrefs = UserPrefs()
        userPrefs.userId = userId
      else:
        userPrefs = searchResults.get()
      userPrefs.email = self.request.get('email')
      userPrefs.addedToGroupNotify = self.request.get('addedToGroupNotify')
      userPrefs.otherMemberEnteredOrLeftNotify = self.request.get('otherMemberEnteredOrLeftNotify')
      userPrefs.consentNotify = self.request.get('consentNotify')
      userPrefs.put()

  def HandleGetUserPrefs(self):
    userId = self.request.get('userId')
    searchResults = UserPrefs.gql('WHERE userId = :1', userId)
    if (searchResults.count() > 1):
      self.response.out.write('Error in DB, more than one userPrefs for this userId!')
    elif (searchResults.count() == 0):
      userPrefs = UserPrefs()
      userPrefs.userId = userId
      userPrefs.email = ' '
      userPrefs.addedToGroupNotify = '0'
      userPrefs.otherMemberEnteredOrLeftNotify = '0'
      userPrefs.consentNotify = '0'
      userPrefs.put()
    else:  
      userPrefs = searchResults.get()
    userPrefsResults = []
    userPrefsItem = { 'email' : userPrefs.email, 
                   'addedToGroupNotify' : userPrefs.addedToGroupNotify,
                   'otherMemberEnteredOrLeftNotify' : userPrefs.otherMemberEnteredOrLeftNotify,
                   'consentNotify' : userPrefs.consentNotify  }
    userPrefsResults.append(userPrefsItem)
    self.response.out.write(json.write(userPrefsResults))
      
  def HandleLeaveGroup(self):
    groupKeyStr = self.request.get('groupKey')
    userId = self.request.get('userId')
    #delete group member
    groupMemberResults = GroupMember.gql('WHERE groupKey = :1 AND userId = :2', groupKeyStr,userId)
    if (groupMemberResults.count() != 1):
      self.DebugPrint('Error, did not find exaclty one group member with this userId in this group')
    else:
      member = groupMemberResults.get() 
      member.delete()
      #also delete group if it's empty
      otherGroupMemberResults = GroupMember.gql('WHERE groupKey = :1', groupKeyStr)
      count = otherGroupMemberResults.count()
      groupKey = db.Key(groupKeyStr)
      groupResults = Group.gql('WHERE __key__ = :1', groupKey)
      group = groupResults.get()
      if (count == 0):
        group.delete()
      else:
        #group has other members, so notify them
        for otherMember in otherGroupMemberResults:
          otherMember.newUpdate = '1'
          otherMember.put()
          userPrefsResults = UserPrefs.gql('WHERE userId = :1', otherMember.userId)
          count = userPrefsResults.count()
          if (count != 1 ):
            self.DebugPrint('Did not find exacly one userPrefs for this user')
          else:
            userPrefs = userPrefsResults.get()
            if (userPrefs.otherMemberEnteredOrLeftNotify == '1'):
              message = mail.EmailMessage(sender = "CatchAMovie.Admin@gmail.com",
                                          to = userPrefs.email)
              message.subject = unicode("עזב את הקבוצה", "utf-8") + ": " + group.name + " " + member.userName
              endl = """
"""
              line0 = unicode(":CatchAMovie התראת", "utf-8")
              line1 = unicode("עזב את הקבוצה", "utf-8") + ": " + group.name + " " + member.userName
              line2 = "http://www.igoogle.com/ " + unicode(":לינק לאתר אייגוגל","utf-8") 
              message.body = line0 + endl + endl + line1 + endl + endl + line2
              message.send()

  def HandleAddChatLineToGroup(self):
    groupKeyStr = self.request.get('groupKey')
    groupKey = db.Key(groupKeyStr)
    groupResults = Group.gql('WHERE __key__ = :1', groupKey)
    count = groupResults.count()
    if (count != 1):
      self.DebugPrint('Did not find exactly one group with this group key')
    else:
      group = groupResults.get()
      userName = self.request.get('userName')
      timeStamp = self.request.get('timeStamp')
      line = self.request.get('line')
      userId = self.request.get('userId')
      group.chat.append(timeStamp)
      group.chat.append(userName)
      group.chat.append(line)
      group.chat.append(userId)
      group.put()
      #raise the newUpdate flag for other group members
      otherGroupMembersResults = GroupMember.gql('WHERE groupKey = :1', groupKeyStr)
      for otherMember in otherGroupMembersResults:
        if (otherMember.userId != userId):
          otherMember.newUpdate = '1'
          otherMember.put()
      
  def HandleGetGroupChat(self):
    groupKeyStr = self.request.get('groupKey')
    groupKey = db.Key(groupKeyStr)
    groupResults = Group.gql('WHERE __key__ = :1', groupKey)
    count = groupResults.count()
    if (count != 1):
      self.DebugPrint('Did not find exactly one group with this group key')
    else:
      chat = groupResults.get().chat
      numOfChatLines = len(chat)/4
      chatOutput = []
      for i in range(numOfChatLines):
        #i start from 0
        timeStamp = chat[4*i]
        userName = chat[4*i+1]
        line = chat[4*i+2]
        userId = chat[4*i+3]
        chatLine = { 'timeStamp' : timeStamp,
                     'userName' : userName,
                     'line' : line,
                     'userId' : userId }
        chatOutput.append(chatLine)
      self.response.out.write(json.write(chatOutput))

  def HandleGetNewMoviesDapp(self):
    searchResults = NewMoviesContent.all()
    try:
      if (searchResults.count() == 0):
        response = urlfetch.fetch(url=self.newMoviesUrl,deadline=10)
        if (response.status_code != 200):
          errorOutput = []
          errorLine = {'error' : '2' }
          errorOutput.append(errorLine)
          self.response.out.write(json.write(errorOutput))
        else:
          self.response.out.write(response.content)
          newMoviesContent = NewMoviesContent()
          newMoviesContent.content = response.content
          timeStr = time.localtime()
          currentWeek = int(time.strftime("%U", timeStr))
          currentDay = int(time.strftime("%w", timeStr))
          currentHour = int(time.strftime("%H", timeStr))
          if ((currentDay < 4) or ((currentDay == 4) and (currentHour < 10))):
            newMoviesContent.weekOfUpdate = currentWeek - 1
          else:
            newMoviesContent.weekOfUpdate = currentWeek              
          newMoviesContent.put()
      else:
        newMoviesContentFromCache = searchResults.get()
        timeStr = time.localtime()
        currentWeek = int(time.strftime("%U", timeStr))
        currentDay = int(time.strftime("%w", timeStr))
        currentHour = int(time.strftime("%H", timeStr))
        weekOfUpdate = newMoviesContentFromCache.weekOfUpdate
        #check if cache content is valid
        if ((weekOfUpdate == currentWeek) or ((weekOfUpdate == currentWeek -1) and ((currentDay < 4) or ((currentDay == 4) and (currentHour < 10))))):
          #cache content valid                                    
          self.response.out.write(newMoviesContentFromCache.content)
        else:
          #cache content not valid, delete old record and act the same as if cache was empty
          newMoviesContentFromCache.delete()
          response = urlfetch.fetch(url=self.newMoviesUrl,deadline=10)                                    
          if (response.status_code != 200):
            errorOutput = []
            errorLine = {'error' : '2' }
            errorOutput.append(errorLine)
            self.response.out.write(json.write(errorOutput))
          else:
            self.response.out.write(response.content)
            newMoviesContent = NewMoviesContent()
            newMoviesContent.content = response.content
            timeStr = time.localtime()
            currentWeek = int(time.strftime("%U", timeStr))
            currentDay = int(time.strftime("%w", timeStr))
            currentHour = int(time.strftime("%H", timeStr))
            if ((currentDay < 4) or ((currentDay == 4) and (currentHour < 10))):
              newMoviesContent.weekOfUpdate = currentWeek - 1
            else:
              newMoviesContent.weekOfUpdate = currentWeek              
            newMoviesContent.put()
    except urlfetch.Error, e:
      errorOutput = []
      errorLine = {'error' : '2' }
      errorOutput.append(errorLine)
      self.response.out.write(json.write(errorOutput))
      
  def HandleGetAllMoviesDapp(self):
    searchResults = AllMoviesContent.all()
    try:
      if (searchResults.count() == 0):
        response = urlfetch.fetch(url=self.allMoviesUrl,deadline=10)
        if (response.status_code != 200):
          errorOutput = []
          errorLine = {'error' : '2' }
          errorOutput.append(errorLine)
          self.response.out.write(json.write(errorOutput))
        else:
          self.response.out.write(response.content)
          allMoviesContent = AllMoviesContent()
          allMoviesContent.content = response.content
          timeStr = time.localtime()
          currentWeek = int(time.strftime("%U", timeStr))
          currentDay = int(time.strftime("%w", timeStr))
          currentHour = int(time.strftime("%H", timeStr))
          if ((currentDay < 4) or ((currentDay == 4) and (currentHour < 10))):
            allMoviesContent.weekOfUpdate = currentWeek - 1
          else:
            allMoviesContent.weekOfUpdate = currentWeek
          self.HandleParseAllMovieIds(allMoviesContent)
          allMoviesContent.put()
      else:
        allMoviesContentFromCache = searchResults.get()
        timeStr = time.localtime()
        currentWeek = int(time.strftime("%U", timeStr))
        currentDay = int(time.strftime("%w", timeStr))
        currentHour = int(time.strftime("%H", timeStr))
        weekOfUpdate = allMoviesContentFromCache.weekOfUpdate
        #check if cache content is valid
        if ((weekOfUpdate == currentWeek) or ((weekOfUpdate == currentWeek -1) and ((currentDay < 4) or ((currentDay == 4) and (currentHour < 10))))):
          #cache content valid                                    
          self.response.out.write(allMoviesContentFromCache.content)
        else:
          #cache content not valid, delete old record and act the same as if cache was empty
          allMoviesContentFromCache.delete()
          response = urlfetch.fetch(url=self.allMoviesUrl,deadline=10)                                    
          if (response.status_code != 200):
            errorOutput = []
            errorLine = {'error' : '2' }
            errorOutput.append(errorLine)
            self.response.out.write(json.write(errorOutput))
          else:
            self.response.out.write(response.content)
            allMoviesContent = AllMoviesContent()
            allMoviesContent.content = response.content
            timeStr = time.localtime()
            currentWeek = int(time.strftime("%U", timeStr))
            currentDay = int(time.strftime("%w", timeStr))
            currentHour = int(time.strftime("%H", timeStr))
            if ((currentDay < 4) or ((currentDay == 4) and (currentHour < 10))):
              allMoviesContent.weekOfUpdate = currentWeek - 1
            else:
              allMoviesContent.weekOfUpdate = currentWeek
            self.HandleParseAllMovieIds(allMoviesContent)  
            allMoviesContent.put()
    except urlfetch.Error, e:
      errorOutput = []
      errorLine = {'error' : '2' }
      errorOutput.append(errorLine)
      self.response.out.write(json.write(errorOutput))     

  def HandleGetSingleMovieDapp(self):
    movieId = self.request.get('movieId')
    searchResults = SingleMovieContent.gql('WHERE movieId = :1', movieId )
    if (searchResults.count() == 0):
      errorOutput = []
      errorLine = {'error' : '1' }
      errorOutput.append(errorLine)
      self.response.out.write(json.write(errorOutput))
      concatUrl = self.singleMovieUrl + movieId
      response = urlfetch.fetch(url=concatUrl,deadline=10)
      if (response.status_code == 200):
        singleMovieContent = SingleMovieContent()
        singleMovieContent.movieId = movieId
        singleMovieContent.content = response.content
        timeStr = time.localtime()
        currentWeek = int(time.strftime("%U", timeStr))
        currentDay = int(time.strftime("%w", timeStr))
        currentHour = int(time.strftime("%H", timeStr))
        if ((currentDay < 4) or ((currentDay == 4) and (currentHour < 10))):
          singleMovieContent.weekOfUpdate = currentWeek - 1
        else:
          singleMovieContent.weekOfUpdate = currentWeek              
        singleMovieContent.put()
    else:
      singleMovieContentFromCache = searchResults.get()
      timeStr = time.localtime()
      currentWeek = int(time.strftime("%U", timeStr))
      currentDay = int(time.strftime("%w", timeStr))
      currentHour = int(time.strftime("%H", timeStr))
      weekOfUpdate = singleMovieContentFromCache.weekOfUpdate
      #check if cache content is valid
      if ((weekOfUpdate == currentWeek) or ((weekOfUpdate == currentWeek -1) and ((currentDay < 4) or ((currentDay == 4) and (currentHour < 10))))):
        #cache content valid                                    
        self.response.out.write(singleMovieContentFromCache.content)
      else:
        #cache content not valid, delete old record and act the same as if cache was empty
        singleMovieContentFromCache.delete()
        errorOutput = []
        errorLine = {'error' : '1' }
        errorOutput.append(errorLine)
        self.response.out.write(json.write(errorOutput))
        concatUrl = self.singleMovieUrl + movieId
        response = urlfetch.fetch(url=concatUrl,deadline=10)                                    
        if (response.status_code == 200):
          singleMovieContent = SingleMovieContent()
          singleMovieContent.movieId = movieId
          singleMovieContent.content = response.content
          timeStr = time.localtime()
          currentWeek = int(time.strftime("%U", timeStr))
          currentDay = int(time.strftime("%w", timeStr))
          currentHour = int(time.strftime("%H", timeStr))
          if ((currentDay < 4) or ((currentDay == 4) and (currentHour < 10))):
            singleMovieContent.weekOfUpdate = currentWeek - 1
          else:
            singleMovieContent.weekOfUpdate = currentWeek              
          singleMovieContent.put()

  def HandleParseAllMovieIds(self, allMoviesContent):
    allMoviesContent.parsedMovieIds = []
    for i in range(100):
      allMoviesContent.parsedMovieIds.append('x')
    splitList = allMoviesContent.content.split('MID=')
    for i in range(len(splitList) -2): 
      allMoviesContent.parsedMovieIds[i] = splitList[i+1][0] + splitList[i+1][1] + splitList[i+1][2] + splitList[i+1][3]
    allMoviesContent.put()

  def HandleGetMoviePreview(self):
    movieId = self.request.get('movieId')
    concatUrl = "http://www.seret.co.il/movies/s_movies.asp?MID=" + movieId
    response = urlfetch.fetch(url=concatUrl,deadline=10)
    if (response.status_code == 200):
      list1 = response.content.split('<div id="divDescText" class="text14">')
      list2 = list1[1].split('<')
##      textLine = {'text' : list2[0] }
      hebText = unicode(" " + list2[0]+ " " , "utf-8")
      self.response.out.write(hebText)
    
#for debug purposes only:
  def HandleClearGroupChat(self):
    groupKeyStr = self.request.get('groupKey')
    groupKey = db.Key(groupKeyStr)
    groupResults = Group.gql('WHERE __key__ = :1', groupKey)
    count = groupResults.count()
    if (count != 1):
      self.DebugPrint('Did not find exactly one group with this group key')
    else:
      group = groupResults.get()
      group.chat = []
      group.put()
      
  
       
  


class UpdateMewMoviesAppHandler(webapp.RequestHandler):
  debugVersion = False
  logLineNum = 0
  numOfRetries = 0
  newMoviesUrl = "http://www.dapper.net/transform.php?dappName=catchamovieNewMoiesVersion2&transformer=JSON&applyToUrl=http%3A%2F%2Fwww.seret.co.il%2Fmovies%2Findex.asp%3FcatCase%3D1"

  def get(self):   
    self.HandleUpdateNewMoviesDapp()
   
  def HandleUpdateNewMoviesDapp(self):   
    try:
      response = urlfetch.fetch(url=self.newMoviesUrl,deadline=10)
      if (response.status_code != 200):
        self.numOfRetries = self.numOfRetries + 1
        time.sleep(1)
        if (self.numOfRetries < 10):
          self.HandleUpdateNewMoviesDapp()
      elif (response.content[2] != 'd'):
        self.numOfRetries = self.numOfRetries + 1
        time.sleep(1)
        if (self.numOfRetries < 10):
          self.HandleUpdateAllMoviesDapp()    
    except urlfetch.Error, e:
      self.numOfRetries = self.numOfRetries + 1
      time.sleep(1)
      if (self.numOfRetries < 10):
        self.HandleUpdateNewMoviesDapp()
    searchResults = NewMoviesContent.all()
    if (searchResults.count() > 1):
      self.DebugPrint('Found more than one NewMoviesContent (found %s), Deleting previous' %searchResults.count())
      for newMoviesContent in searchResults:
        newMoviesContent.delete()
      newMoviesContent = NewMoviesContent()  
    else:
      if (searchResults.count() == 1):
        newMoviesContent = searchResults.get()
      else:
        #searchResults.count() == 0
        self.DebugPrint('Did not find an old record, creating new')
        newMoviesContent = NewMoviesContent()
    newMoviesContent.content = response.content
    #update to current week anyway!
    timeStr = time.localtime()
    newMoviesContent.weekOfUpdate = int(time.strftime("%U", timeStr))
    newMoviesContent.put()

  def DebugPrint(self, text):
    if (self.debugVersion):
      self.response.out.write('$ '+ text+ ' $')
    newLogLine = UpdateLogLine()
    self.logLineNum = self.logLineNum + 1
    newLogLine.lineNum = self.logLineNum
    newLogLine.time = time.strftime("%H:%M:%S", time.localtime())
    newLogLine.content = text
    newLogLine.put()      
                                            


class UpdateAllMoviesAppHandler(webapp.RequestHandler):
  debugVersion = False
  logLineNum = 0
  numOfRetries = 0
  allMoviesUrl = "http://www.dapper.net/transform.php?dappName=catchamovieAllMovies&transformer=JSON&applyToUrl=http%3A%2F%2Fwww.seret.co.il%2Fmovies%2Findex.asp%3FcatCase%3D2"

  def get(self):   
    self.HandleUpdateAllMoviesDapp()
   
  def HandleUpdateAllMoviesDapp(self):   
    try:
      response = urlfetch.fetch(url=self.allMoviesUrl,deadline=10)
      if (response.status_code != 200):
        self.numOfRetries = self.numOfRetries + 1
        time.sleep(1)
        if (self.numOfRetries < 10):
          self.HandleUpdateAllMoviesDapp()
      elif (response.content[2] != 'd'):
        self.numOfRetries = self.numOfRetries + 1
        time.sleep(1)
        if (self.numOfRetries < 10):
          self.HandleUpdateAllMoviesDapp()
    except urlfetch.Error, e:
      self.numOfRetries = self.numOfRetries + 1
      time.sleep(1)
      if (self.numOfRetries < 10):
        self.HandleUpdateAllMoviesDapp()
    searchResults = AllMoviesContent.all()
    if (searchResults.count() > 1):
      self.DebugPrint('Found more than one AllMoviesContent (found %s), Deleting previous' %searchResults.count())
      for allMoviesContent in searchResults:
        allMoviesContent.delete()
      allMoviesContent = AllMoviesContent()  
    else:
      if (searchResults.count() == 1):
        allMoviesContent = searchResults.get()
##        allMoviesContent = AllMoviesContent()  debug: create double!
      else:
        #searchResults.count() == 0
        self.DebugPrint('Did not find an old record, creating new')
        allMoviesContent = AllMoviesContent()
    allMoviesContent.content = response.content  
    #update to current week anyway!
    timeStr = time.localtime()
    allMoviesContent.weekOfUpdate = int(time.strftime("%U", timeStr))
    self.HandleParseAllMovieIds(allMoviesContent)
    allMoviesContent.put()

    
  def HandleParseAllMovieIds(self, allMoviesContent):
    allMoviesContent.parsedMovieIds = []
    for i in range(100):
      allMoviesContent.parsedMovieIds.append('x')
    splitList = allMoviesContent.content.split('MID=')
    for i in range(len(splitList) -2): 
      allMoviesContent.parsedMovieIds[i] = splitList[i+1][0] + splitList[i+1][1] + splitList[i+1][2] + splitList[i+1][3]
##      allMoviesContent.parsedMovieIds[i] = splitList[i+1][0] + splitList[i+1][0] + splitList[i+1][0] + splitList[i+1][0] debug: check list update
    allMoviesContent.put()  

  
  def DebugPrint(self, text):
    if (self.debugVersion):
      self.response.out.write('$ '+ text+ ' $')
    newLogLine = UpdateLogLine()
    self.logLineNum = self.logLineNum + 1
    newLogLine.lineNum = self.logLineNum
    newLogLine.time = time.strftime("%H:%M:%S", time.localtime())
    newLogLine.content = text
    newLogLine.put()
  

class UpdateSingleMovieAppHandler(webapp.RequestHandler):
  debugVersion = False
  logLineNum = 0
  numOfRetries = 0
  singleMovieUrl = "http://www.dapper.net/transform.php?dappName=CAMSingleMovieDapper2&transformer=JSON&v_movieId="

  def get(self):   
    self.HandleUpdateSingleMovieDapp()

  def HandleUpdateSingleMovieDapp(self):
    searchResults1 = CurrentParsedMovie.all()
    currentParsedMovie = searchResults1.get()
    searchResults2 = AllMoviesContent.all()
    allMoviesContent = searchResults2.get()
    i = 0
    while (i<4):
      movieId = allMoviesContent.parsedMovieIds[currentParsedMovie.listIndex]
      if (movieId != 'x'):
        concatUrl = self.singleMovieUrl + movieId
        try:
          response = urlfetch.fetch(url=concatUrl,deadline=10)  
          searchResults3 = SingleMovieContent.gql('WHERE movieId = :1', movieId )
          if (searchResults3.count() > 1):
            self.DebugPrint('Found more than one SingleMovieContent (found %s), Deleting previous ' %searchResults3.count())
            for singleMovieContent in searchResults3:
              singleMovieContent.delete()
            singleMovieContent = SingleMovieContent() 
          else:
            if (searchResults3.count() == 1):
              singleMovieContent = searchResults3.get()
            else:
              #searchResults.count() == 0
              singleMovieContent = SingleMovieContent()
          singleMovieContent.content = response.content
          singleMovieContent.movieId = movieId
          #update to current week anyway!
          timeStr = time.localtime()
          singleMovieContent.weekOfUpdate = int(time.strftime("%U", timeStr))
          singleMovieContent.put()
          currentParsedMovie.listIndex = currentParsedMovie.listIndex + 1
          if (currentParsedMovie.listIndex == 64):
            currentParsedMovie.listIndex = 0
          currentParsedMovie.put()
##        self.DebugPrint('Saved Movie with id %s' %movieId)
          time.sleep(1)
        except urlfetch.Error, e:
          #try again
          i = i -1  
      else:
        currentParsedMovie.listIndex = currentParsedMovie.listIndex + 1
        if (currentParsedMovie.listIndex == 64):
          currentParsedMovie.listIndex = 0 
        currentParsedMovie.put()
      i = i + 1  
    
    

  def DebugPrint(self, text):
    if (self.debugVersion):
      self.response.out.write('$ '+ text+ ' $')
    newLogLine = UpdateLogLine()
    self.logLineNum = self.logLineNum + 1
    newLogLine.lineNum = self.logLineNum
    newLogLine.time = time.strftime("%H:%M:%S", time.localtime())
    newLogLine.content = text
    newLogLine.put()  
    
##Time function:
##self.DebugPrint('time= %s' %time.strftime("%H:%M:%S", time.localtime()))       

application = webapp.WSGIApplication(
                                     [('/', MainAppHandler),('/updatenewmovies', UpdateMewMoviesAppHandler),('/updateallmovies', UpdateAllMoviesAppHandler),('/updatesinglemovie', UpdateSingleMovieAppHandler)],
                                     debug=True)

def main():
  run_wsgi_app(application)

if __name__ == "__main__":
  main()
